Package org.python.core

Source Code of org.python.core.Py

// Copyright (c) Corporation for National Research Initiatives
package org.python.core;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.ObjectStreamException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.Serializable;
import java.io.StreamCorruptedException;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;

import org.python.compiler.Module;
import org.python.core.adapter.ClassicPyObjectAdapter;
import org.python.core.adapter.ExtensiblePyObjectAdapter;
import org.python.parser.ast.modType;
import org.python.pydev.jython.ExitScriptException;

public final class Py {
    static boolean frozen;
    static String frozenPackage = null;
    private final static Object PRESENT = new Object();
    static java.util.Hashtable frozenModules;

    static boolean initialized;

    static class SingletonResolver implements Serializable {
        private String which;

        SingletonResolver(String which) {
            this.which = which;
        }

        private Object readResolve() throws ObjectStreamException {
            if (which.equals("None")) {
                return Py.None;
            } else if (which.equals("Ellipsis")) {
                return Py.Ellipsis;
            } else if (which.equals("NotImplemented")) {
                return Py.NotImplemented;
            }
            throw new StreamCorruptedException("unknown singleton: " + which);
        }
    }

    /* Holds the singleton None and Ellipsis objects */
    /** The singleton None Python object **/
    public static PyObject None;

    /** The singleton Ellipsis Python object - written as ... when indexing */
    public static PyObject Ellipsis;

    /** The singleton NotImplemented Python object. Used in rich comparison */
    public static PyObject NotImplemented;

    /** A zero-length array of Strings to pass to functions that
        don't have any keyword arguments **/
    public static String[] NoKeywords;

    /** A zero-length array of PyObject's to pass to functions that
        expect zero-arguments **/
    public static PyObject[] EmptyObjects;

    /** A tuple with zero elements **/
    public static PyTuple EmptyTuple;

    /** The Python integer 0 - also used as false **/
    public static PyInteger Zero;

    /** The Python integer 1 - also used as true **/
    public static PyInteger One;

    /** A zero-length Python string **/
    public static PyString EmptyString;

    /** A Python string containing '\n' **/
    public static PyString Newline;

    /** A Python string containing ' ' **/
    public static PyString Space;

    /** A unique object to indicate no conversion is possible
        in __tojava__ methods **/
    public static Object NoConversion;

    public static PyObject OSError;
    public static PyObject NotImplementedError;
    public static PyObject EnvironmentError;

    /* The standard Python exceptions */
    public static PyObject OverflowError;

    public static PyException OverflowError(String message) {
        return new PyException(Py.OverflowError, message);
    }

    public static PyObject RuntimeError;

    public static PyException RuntimeError(String message) {
        return new PyException(Py.RuntimeError, message);
    }

    public static PyObject KeyboardInterrupt;
    /*public static PyException KeyboardInterrupt(String message) {
      return new PyException(Py.KeyboardInterrupt, message);
      }*/

    public static PyObject FloatingPointError;

    public static PyException FloatingPointError(String message) {
        return new PyException(Py.FloatingPointError, message);
    }

    public static PyObject SyntaxError;

    public static PyException SyntaxError(String message) {
        return new PyException(Py.SyntaxError, message);
    }

    public static PyObject IndentationError;
    public static PyObject TabError;

    public static PyObject AttributeError;

    public static PyException AttributeError(String message) {
        return new PyException(Py.AttributeError, message);
    }

    public static PyObject IOError;

    public static PyException IOError(java.io.IOException ioe) {
        //System.err.println("ioe: "+ioe);
        //ioe.printStackTrace();
        String message = ioe.getMessage();
        if (ioe instanceof java.io.FileNotFoundException) {
            message = "File not found - " + message;
        }
        return new PyException(Py.IOError, message);
    }

    public static PyException IOError(String message) {
        //System.err.println("sioe: "+message);
        return new PyException(Py.IOError, message);
    }

    public static PyObject KeyError;

    public static PyException KeyError(String message) {
        return new PyException(Py.KeyError, message);
    }

    public static PyObject AssertionError;

    public static PyException AssertionError(String message) {
        return new PyException(Py.AssertionError, message);
    }

    public static PyObject TypeError;

    public static PyException TypeError(String message) {
        return new PyException(Py.TypeError, message);
    }

    public static PyObject ReferenceError;

    public static PyException ReferenceError(String message) {
        return new PyException(Py.ReferenceError, message);
    }

    public static PyObject SystemError;

    public static PyException SystemError(String message) {
        return new PyException(Py.SystemError, message);
    }

    public static PyObject IndexError;

    public static PyException IndexError(String message) {
        return new PyException(Py.IndexError, message);
    }

    public static PyObject ZeroDivisionError;

    public static PyException ZeroDivisionError(String message) {
        return new PyException(Py.ZeroDivisionError, message);
    }

    public static PyObject NameError;

    public static PyException NameError(String message) {
        return new PyException(Py.NameError, message);
    }

    public static PyObject UnboundLocalError;

    public static PyException UnboundLocalError(String message) {
        return new PyException(Py.UnboundLocalError, message);
    }

    public static PyObject SystemExit;

    /*public static PyException SystemExit(String message) {
      return new PyException(Py.SystemExit, message);
      }*/
    static void maybeSystemExit(PyException exc) {
        //System.err.println("maybeSystemExit: " + exc.type.toString());
        if (Py.matchException(exc, Py.SystemExit)) {
            throw new ExitScriptException(); //We don't want System.exit to actually be called in PyDev.
            //            PyObject value = exc.value;
            //            //System.err.println("exiting: "+value.getClass().getName());
            //            if (value instanceof PyInstance) {
            //                PyObject tmp = value.__findattr__("code");
            //                if (tmp != null)
            //                    value = tmp;
            //            }
            //            Py.getSystemState().callExitFunc();
            //            if (value instanceof PyInteger) {
            //                System.exit(((PyInteger)value).getValue());
            //            } else {
            //                if (value != Py.None) {
            //                    try {
            //                        Py.println(value);
            //                        System.exit(1);
            //                    }
            //                    catch (Throwable t0) { }
            //                }
            //                System.exit(0);
            //            }
        }
    }

    public static PyObject StopIteration;

    public static PyException StopIteration(String message) {
        return new PyException(Py.StopIteration, message);
    }

    public static PyObject ImportError;

    public static PyException ImportError(String message) {
        return new PyException(Py.ImportError, message);
    }

    public static PyObject ValueError;

    public static PyException ValueError(String message) {
        return new PyException(Py.ValueError, message);
    }

    public static PyObject UnicodeError;

    public static PyException UnicodeError(String message) {
        return new PyException(Py.UnicodeError, message);
    }

    public static PyObject EOFError;

    public static PyException EOFError(String message) {
        return new PyException(Py.EOFError, message);
    }

    public static PyObject MemoryError;

    public static void memory_error(OutOfMemoryError t) {
        if (Options.showJavaExceptions) {
            t.printStackTrace();
        }
        // this logic would allow to re-enable the old behavior when it makes sense,
        // or better offer a hook?
        //        try {
        //            byte[] alloc = new byte[(512*1024)];
        //        } catch(OutOfMemoryError oome) {
        //            System.err.println("Out Of Memory");
        //            System.err.println("You might want to try the -mx flag to increase heap size.");
        //            System.exit(-1);
        //        }
    }

    public static PyException MemoryError(String message) {
        return new PyException(Py.MemoryError, message);
    }

    public static PyObject ArithmeticError;
    public static PyObject LookupError;
    public static PyObject StandardError;
    public static PyObject Exception;

    public static PyObject Warning;

    public static void Warning(String message) {
        warning(Warning, message);
    }

    public static PyObject UserWarning;

    public static void UserWarning(String message) {
        warning(UserWarning, message);
    }

    public static PyObject DeprecationWarning;

    public static void DeprecationWarning(String message) {
        warning(DeprecationWarning, message);
    }

    public static PyObject SyntaxWarning;

    public static void SyntaxWarning(String message) {
        warning(SyntaxWarning, message);
    }

    public static PyObject OverflowWarning;

    public static void OverflowWarning(String message) {
        warning(OverflowWarning, message);
    }

    public static PyObject RuntimeWarning;

    public static void RuntimeWarning(String message) {
        warning(RuntimeWarning, message);
    }

    private static PyObject warnings_mod;

    private static PyObject importWarnings() {
        if (warnings_mod != null)
            return warnings_mod;
        PyObject mod;
        try {
            mod = __builtin__.__import__("warnings");
        } catch (PyException e) {
            if (matchException(e, ImportError)) {
                return null;
            }
            throw e;
        }
        warnings_mod = mod;
        return mod;
    }

    private static String warn_hcategory(PyObject category) {
        PyObject name = category.__findattr__("__name__");
        if (name != null)
            return "[" + name + "]";
        return "[warning]";
    }

    public static void warning(PyObject category, String message) {
        PyObject func = null;
        PyObject mod = importWarnings();
        if (mod != null)
            func = mod.__getattr__("warn");
        if (func == null) {
            System.err.println(warn_hcategory(category) + ": " + message);
            return;
        } else {
            func.__call__(Py.newString(message), category);
        }
    }

    public static void warning(PyObject category, String message, String filename, int lineno, String module,
            PyObject registry) {
        PyObject func = null;
        PyObject mod = importWarnings();
        if (mod != null)
            func = mod.__getattr__("warn_explicit");
        if (func == null) {
            System.err.println(filename + ":" + lineno + ":" + warn_hcategory(category) + ": " + message);
            return;
        } else {
            func.__call__(
                    new PyObject[] { Py.newString(message), category, Py.newString(filename), Py.newInteger(lineno),
                            (module == null) ? Py.None : Py.newString(module), registry }, Py.NoKeywords);
        }
    }

    public static PyObject JavaError;

    public static PyException JavaError(Throwable t) {
        if (t instanceof PyException) {
            return (PyException) t;
        } else if (t instanceof InvocationTargetException) {
            return JavaError(((InvocationTargetException) t).getTargetException());
        } else if (t instanceof OutOfMemoryError) {
            memory_error((OutOfMemoryError) t);
        }
        PyJavaInstance exc = new PyJavaInstance(t);
        return new PyException(exc.instclass, exc);
    }

    // Don't allow any constructors. Class only provides static methods.
    private Py() {
        ;
    }

    /** @deprecated **/
    //public static InterpreterState interp;

    /**
       Convert a given <code>PyObject</code> to an instance of a Java class.
       Identical to <code>o.__tojava__(c)</code> except that it will
       raise a <code>TypeError</code> if the conversion fails.

       @param o the <code>PyObject</code> to convert.
       @param c the class to convert it to.
    **/
    public static Object tojava(PyObject o, Class c) {
        Object obj = o.__tojava__(c);
        if (obj == Py.NoConversion) {
            throw Py.TypeError("can't convert " + o.__repr__() + " to " + c.getName());
        }
        return obj;
    }

    // ??pending: was @deprecated but is actually used by proxie code.
    // Can get rid of it?
    public static Object tojava(PyObject o, String s) {
        Class c = findClass(s);
        if (c == null)
            throw Py.TypeError("can't convert to: " + s);
        return tojava(o, c); // prev:Class.forName
    }

    /* Helper functions for PyProxy's */

    /** @deprecated * */
    public static PyObject jfindattr(PyProxy proxy, String name) {
        PyInstance o = proxy._getPyInstance();
        if (o == null) {
            proxy.__initProxy__(new Object[0]);
            o = proxy._getPyInstance();
        }
        PyObject ret = o.__jfindattr__(name);
        if (ret == null)
            return null;

        // Set the current system state to match proxy -- usually
        // this is a waste of time :-(
        Py.setSystemState(proxy._getPySystemState());
        return ret;
    }

    /** @deprecated * */
    public static PyObject jgetattr(PyProxy proxy, String name) {
        PyInstance o = proxy._getPyInstance();
        if (o == null) {
            proxy.__initProxy__(new Object[0]);
            o = proxy._getPyInstance();
        }
        PyObject ret = o.__jfindattr__(name);
        if (ret == null)
            throw Py.AttributeError("abstract method \"" + name + "\" not implemented");
        // Set the current system state to match proxy -- usually this is a
        // waste of time :-(
        Py.setSystemState(proxy._getPySystemState());
        return ret;
    }

    /* Convenience methods to create new constants without using "new" */
    private static PyInteger[] integerCache = null;

    public static final PyInteger newInteger(int i) {
        if (integerCache == null) {
            integerCache = new PyInteger[1000];
            for (int j = -100; j < 900; j++) {
                integerCache[j + 100] = new PyInteger(j);
            }
        }
        if (i >= -100 && i < 900) {
            return integerCache[i + 100];
        } else {
            return new PyInteger(i);
        }
    }

    public static PyObject newInteger(long i) {
        if (i < Integer.MIN_VALUE || i > Integer.MAX_VALUE)
            return new PyLong(i);
        else
            return newInteger((int) i);
    }

    public static PyLong newLong(String s) {
        return new PyLong(s);
    }

    public static PyLong newLong(java.math.BigInteger i) {
        return new PyLong(i);
    }

    public static PyLong newLong(int i) {
        return new PyLong(i);
    }

    public static PyComplex newImaginary(double v) {
        return new PyComplex(0, v);
    }

    public static PyFloat newFloat(float v) {
        return new PyFloat((double) v);
    }

    public static PyFloat newFloat(double v) {
        return new PyFloat(v);
    }

    public static PyString newString(char c) {
        return makeCharacter(c);
    }

    public static PyString newString(String s) {
        return new PyString(s);
    }

    public static PyUnicode newUnicode(char c) {
        return (PyUnicode) makeCharacter(c, true);
    }

    public static PyUnicode newUnicode(String s) {
        return new PyUnicode(s);
    }

    public static PyInteger newBoolean(boolean t) {
        return t ? Py.One : Py.Zero;
    }

    // nested scopes:
    // String[] cellvars,String[] freevars,int npurecell & int moreflags

    public static PyCode newCode(int argcount, String varnames[], String filename, String name, boolean args,
            boolean keywords, PyFunctionTable funcs, int func_id, String[] cellvars, String[] freevars, int npurecell,
            int moreflags) {
        return new PyTableCode(argcount, varnames, filename, name, 0, args, keywords, funcs, func_id, cellvars,
                freevars, npurecell, moreflags);
    }

    public static PyCode newCode(int argcount, String varnames[], String filename, String name, int firstlineno,
            boolean args, boolean keywords, PyFunctionTable funcs, int func_id, String[] cellvars, String[] freevars,
            int npurecell, int moreflags)

    {
        return new PyTableCode(argcount, varnames, filename, name, firstlineno, args, keywords, funcs, func_id,
                cellvars, freevars, npurecell, moreflags);
    }

    // --

    public static PyCode newCode(int argcount, String varnames[], String filename, String name, boolean args,
            boolean keywords, PyFunctionTable funcs, int func_id) {
        return new PyTableCode(argcount, varnames, filename, name, 0, args, keywords, funcs, func_id);
    }

    public static PyCode newCode(int argcount, String varnames[], String filename, String name, int firstlineno,
            boolean args, boolean keywords, PyFunctionTable funcs, int func_id) {
        return new PyTableCode(argcount, varnames, filename, name, firstlineno, args, keywords, funcs, func_id);
    }

    public static PyCode newJavaCode(Class cls, String name) {
        return new JavaCode(newJavaFunc(cls, name));
    }

    public static PyObject newJavaFunc(Class cls, String name) {
        try {
            java.lang.reflect.Method m = cls.getMethod(name, new Class[] { PyObject[].class, String[].class });
            return new JavaFunc(m);
        } catch (NoSuchMethodException e) {
            throw Py.JavaError(e);
        }
    }

    private static PyObject initExc(String name, PyObject exceptions, PyObject dict) {
        PyObject tmp = exceptions.__getattr__(name);
        dict.__setitem__(name, tmp);
        return tmp;
    }

    static void initClassExceptions(PyObject dict) {
        PyObject exc = imp.load("exceptions");

        Exception = initExc("Exception", exc, dict);
        SystemExit = initExc("SystemExit", exc, dict);
        StopIteration = initExc("StopIteration", exc, dict);
        StandardError = initExc("StandardError", exc, dict);
        KeyboardInterrupt = initExc("KeyboardInterrupt", exc, dict);
        ImportError = initExc("ImportError", exc, dict);
        EnvironmentError = initExc("EnvironmentError", exc, dict);
        IOError = initExc("IOError", exc, dict);
        OSError = initExc("OSError", exc, dict);
        EOFError = initExc("EOFError", exc, dict);
        RuntimeError = initExc("RuntimeError", exc, dict);
        NotImplementedError = initExc("NotImplementedError", exc, dict);
        NameError = initExc("NameError", exc, dict);
        UnboundLocalError = initExc("UnboundLocalError", exc, dict);
        AttributeError = initExc("AttributeError", exc, dict);
        SyntaxError = initExc("SyntaxError", exc, dict);
        IndentationError = initExc("IndentationError", exc, dict);
        TabError = initExc("TabError", exc, dict);
        TypeError = initExc("TypeError", exc, dict);
        AssertionError = initExc("AssertionError", exc, dict);
        LookupError = initExc("LookupError", exc, dict);
        IndexError = initExc("IndexError", exc, dict);
        KeyError = initExc("KeyError", exc, dict);
        ArithmeticError = initExc("ArithmeticError", exc, dict);
        OverflowError = initExc("OverflowError", exc, dict);
        ZeroDivisionError = initExc("ZeroDivisionError", exc, dict);
        FloatingPointError = initExc("FloatingPointError", exc, dict);
        ValueError = initExc("ValueError", exc, dict);
        UnicodeError = initExc("UnicodeError", exc, dict);
        ReferenceError = initExc("ReferenceError", exc, dict);
        SystemError = initExc("SystemError", exc, dict);
        MemoryError = initExc("MemoryError", exc, dict);
        Warning = initExc("Warning", exc, dict);
        UserWarning = initExc("UserWarning", exc, dict);
        DeprecationWarning = initExc("DeprecationWarning", exc, dict);
        SyntaxWarning = initExc("SyntaxWarning", exc, dict);
        OverflowWarning = initExc("OverflowWarning", exc, dict);
        RuntimeWarning = initExc("RuntimeWarning", exc, dict);

        // Pre-initialize the PyJavaClass for OutOfMemoryError so when we need
        // it it creating the pieces for it won't cause an additional out of
        // memory error.  Fix for bug #1654484
        PyJavaClass.lookup(java.lang.OutOfMemoryError.class);
    }

    public static PySystemState defaultSystemState;

    // This is a hack to get initializations to work in proper order
    public static synchronized boolean initPython() {
        PySystemState.initialize();
        return true;
    }

    public static Class relFindClass(Class home, String name) {
        try {
            ClassLoader loader = home.getClassLoader();
            if (loader != null)
                return loader.loadClass(name);
            else
                return Class.forName(name);
        } catch (ClassNotFoundException exc) {
            return null;
        } catch (Throwable t) {
            throw Py.JavaError(t);
        }
    }

    private static boolean secEnv = false;

    public static Class findClass(String name) {
        try {
            ClassLoader classLoader = Py.getSystemState().getClassLoader();
            if (classLoader != null)
                return classLoader.loadClass(name);

            if (!secEnv) {
                try {
                    classLoader = imp.getSyspathJavaLoader();
                } catch (SecurityException e) {
                    secEnv = true;
                }
                if (classLoader != null) {
                    return classLoader.loadClass(name);
                }
            }

            return Class.forName(name);

        } catch (ClassNotFoundException e) {
            //             e.printStackTrace();
            return null;
        } catch (IllegalArgumentException e) {
            //             e.printStackTrace();
            return null;
        } catch (NoClassDefFoundError e) {
            //             e.printStackTrace();
            return null;
        }
    }

    public static Class findClassEx(String name, String reason) {
        try {
            ClassLoader classLoader = Py.getSystemState().getClassLoader();
            if (classLoader != null) {
                writeDebug("import", "trying " + name + " as " + reason + " in classLoader");
                return classLoader.loadClass(name);
            }

            if (!secEnv) {
                try {
                    classLoader = imp.getSyspathJavaLoader();
                } catch (SecurityException e) {
                    secEnv = true;
                }
                if (classLoader != null) {
                    writeDebug("import", "trying " + name + " as " + reason + " in syspath loader");
                    return classLoader.loadClass(name);
                }
            }

            writeDebug("import", "trying " + name + " as " + reason + " in Class.forName");
            return Class.forName(name);
        } catch (ClassNotFoundException e) {
            return null;
        } catch (IllegalArgumentException e) {
            throw JavaError(e);
        } catch (LinkageError e) {
            throw JavaError(e);
        }
    }

    private static void setArgv(String arg0, String[] args) {
        PyObject argv[] = new PyObject[args.length + 1];
        argv[0] = new PyString(arg0);
        for (int i = 1; i < argv.length; i++)
            argv[i] = new PyString(args[i - 1]);
        Py.getSystemState().argv = new PyList(argv);
    }

    private static boolean propertiesInitialized = false;

    private static synchronized void initProperties(String[] args, String[] packages, String[] props,
            String frozenPackage, String[] modules, ClassLoader classLoader) {
        if (!propertiesInitialized) {
            propertiesInitialized = true;

            if (frozenPackage != null) {
                Py.frozen = true;
                if (frozenPackage.length() > 0)
                    Py.frozenPackage = frozenPackage;
            }

            java.util.Properties sprops;
            try {
                sprops = new java.util.Properties(System.getProperties());
            } catch (Throwable t) {
                sprops = new java.util.Properties();
            }

            if (props != null) {
                for (int i = 0; i < props.length; i += 2) {
                    sprops.put(props[i], props[i + 1]);
                }
            }
            //System.err.println("sprops: "+sprops);

            if (args == null)
                args = new String[0];
            PySystemState.initialize(sprops, null, args, classLoader);
        }

        if (modules != null) {
            if (frozenModules == null)
                frozenModules = new java.util.Hashtable();

            // System.err.println("modules: "); // ?? dbg
            for (int i = 0; i < modules.length; i++) {
                String modname = modules[i];
                // System.err.print(modname + " "); // ?? dbg
                frozenModules.put(modname, PRESENT);
                // py pkgs are potentially java pkgs too.
                if (modname.endsWith(".__init__")) {
                    String jpkg = modname.substring(0, modname.length() - 9);
                    PySystemState.add_package(jpkg);
                    // System.err.print(":j "); // ?? dbg
                }
            }
            // System.out.println(); // ?? dbg
        }

        if (packages != null) {
            for (int i = 0; i < packages.length; i += 2) {
                PySystemState.add_package(packages[i], packages[i + 1]);
            }
        }
    }

    public static void initProxy(PyProxy proxy, String module, String pyclass, Object[] args, String[] packages,
            String[] props, boolean frozen) {
        initProxy(proxy, module, pyclass, args, packages, props, null, null);
    }

    public static void initProxy(PyProxy proxy, String module, String pyclass, Object[] args, String[] packages,
            String[] props, String frozenPackage, String[] modules) {
        initProperties(null, packages, props, frozenPackage, modules, proxy.getClass().getClassLoader());

        if (proxy._getPyInstance() != null)
            return;

        ThreadState ts = getThreadState();
        PyInstance instance = ts.getInitializingProxy();
        if (instance != null) {
            if (instance.javaProxy != null)
                throw Py.TypeError("Proxy instance reused");
            instance.javaProxy = proxy;
            proxy._setPyInstance(instance);
            proxy._setPySystemState(ts.systemState);
            return;
        }

        //System.out.println("path: "+sys.path.__str__());
        PyObject mod;
        // ??pending: findClass or should avoid sys.path loading?
        Class modClass = Py.findClass(module + "$_PyInner");
        if (modClass != null) {
            //System.err.println("found as class: "+modClass);
            PyCode code = null;
            try {
                code = ((PyRunnable) modClass.newInstance()).getMain();
            } catch (Throwable t) {
                throw Py.JavaError(t);
            }
            mod = imp.createFromCode(module, code);
        } else {
            mod = imp.importName(module.intern(), false);
            //System.err.println("found as mod: "+mod);
        }
        PyClass pyc = (PyClass) mod.__getattr__(pyclass.intern());

        instance = new PyInstance(pyc);
        instance.javaProxy = proxy;
        proxy._setPyInstance(instance);
        proxy._setPySystemState(ts.systemState);

        PyObject[] pargs;
        if (args == null || args.length == 0) {
            pargs = Py.EmptyObjects;
        } else {
            pargs = new PyObject[args.length];
            for (int i = 0; i < args.length; i++)
                pargs[i] = Py.java2py(args[i]);
        }
        instance.__init__(pargs, Py.NoKeywords);
    }

    public static void initRunnable(String module, PyObject dict) {
        Class mainClass = null;
        try {
            // ??pending: should use Py.findClass?
            mainClass = Class.forName(module);
        } catch (ClassNotFoundException exc) {
            System.err.println("Error running main.  Can't find: " + module);
            System.exit(-1);
        }
        PyCode code = null;
        try {
            code = ((PyRunnable) mainClass.newInstance()).getMain();
        } catch (Throwable t) {
            System.err.println("Invalid class (runnable): " + module + "$py");
            System.exit(-1);
        }
        Py.runCode(code, dict, dict);
    }

    /**
     * Initializes a default PythonInterpreter and runs the code from
     * {@link PyRunnable#getMain} as __main__
     *
     * Called by the code generated in {@link Module#addMain()}
     */
    public static void runMain(PyRunnable main, String[] args) throws Exception {
        initProperties(args, null, null, null, null, main.getClass().getClassLoader());
        try {
            imp.createFromCode("__main__", main.getMain());
        } catch (PyException e) {
            Py.getSystemState().callExitFunc();
            if (Py.matchException(e, Py.SystemExit))
                return;
            throw e;
        }
        Py.getSystemState().callExitFunc();
    }

    public static void runMain(Class mainClass, String[] args, String[] packages, String[] props, String frozenPackage,
            String[] modules) throws Exception {
        //System.err.println("main: "+module);

        initProperties(args, packages, props, frozenPackage, modules, mainClass.getClassLoader());

        try {
            PyCode code = null;
            try {
                code = ((PyRunnable) mainClass.newInstance()).getMain();
            } catch (Throwable t) {
                System.err.println("Invalid class: " + mainClass.getName() + "$py");
                System.exit(-1);
            }
            PyObject mod = imp.createFromCode("__main__", code);
        } catch (PyException e) {
            Py.getSystemState().callExitFunc();
            if (Py.matchException(e, Py.SystemExit))
                return;
            throw e;
        }
        Py.getSystemState().callExitFunc();
    }

    //XXX: this needs review to make sure we are cutting out all of the Java
    //     exceptions.
    private static String getStackTrace(Throwable javaError) {
        ByteArrayOutputStream buf = new ByteArrayOutputStream();
        javaError.printStackTrace(new PrintStream(buf));

        String str = buf.toString();
        int index = -1;
        if (index == -1)
            index = str.indexOf("at org.python.core.PyReflectedConstructor.__call__");
        if (index == -1)
            index = str.indexOf("at org.python.core.PyReflectedFunction.__call__");
        if (index == -1)
            index = str.indexOf("at org/python/core/PyReflectedConstructor.__call__");
        if (index == -1)
            index = str.indexOf("at org/python/core/PyReflectedFunction.__call__");

        if (index != -1)
            index = str.lastIndexOf("\n", index);

        int index0 = str.indexOf("\n");

        if (index >= index0)
            str = str.substring(index0 + 1, index + 1);

        return str;
    }

    /* Display a PyException and stack trace */
    public static void printException(Throwable t) {
        printException(t, null, null);
    }

    public static void printException(Throwable t, PyFrame f) {
        printException(t, f, null);
    }

    public static synchronized void printException(Throwable t, PyFrame f, PyObject file) {
        //System.err.println("printingException: "+t+", "+file);
        StdoutWrapper stderr = Py.stderr;

        if (file != null) {
            stderr = new FixedFileWrapper(file);
        }

        if (Options.showJavaExceptions) {
            stderr.println("Java Traceback:");
            java.io.CharArrayWriter buf = new java.io.CharArrayWriter();
            if (t instanceof PyException) {
                ((PyException) t).super__printStackTrace(new java.io.PrintWriter(buf));
            } else {
                t.printStackTrace(new java.io.PrintWriter(buf));
            }
            stderr.print(buf.toString());
        }

        PyException exc = Py.JavaError(t);

        maybeSystemExit(exc);

        setException(exc, f);

        ThreadState ts = getThreadState();

        ts.systemState.last_value = exc.value;
        ts.systemState.last_type = exc.type;
        ts.systemState.last_traceback = exc.traceback;

        PyObject exceptHook = ts.systemState.__findattr__("excepthook");
        if (exceptHook != null) {
            try {
                exceptHook.__call__(exc.type, exc.value, exc.traceback);
            } catch (PyException exc2) {
                stderr.println("Error in sys.excepthook:");
                displayException(exc2.type, exc2.value, exc2.traceback, file);
                stderr.println();
                stderr.println("Original exception was:");
                displayException(exc.type, exc.value, exc.traceback, file);
            }
        } else {
            stderr.println("sys.excepthook is missing");
            displayException(exc.type, exc.value, exc.traceback, file);
        }

        ts.exception = null;
    }

    public static void displayException(PyObject type, PyObject value, PyObject tb, PyObject file) {
        StdoutWrapper stderr = Py.stderr;
        if (file != null) {
            stderr = new FixedFileWrapper(file);
        }

        if (tb instanceof PyTraceback)
            stderr.print(((PyTraceback) tb).dumpStack());
        if (__builtin__.isinstance(value, (PyClass) Py.SyntaxError)) {
            stderr.println("  File \"" + value.__findattr__("filename") + "\", line " + value.__findattr__("lineno"));
            PyObject text = value.__findattr__("text");
            if (text != Py.None && text.__len__() != 0) {
                stderr.println("\t" + text);
                String space = "\t";
                int col = ((PyInteger) value.__findattr__("offset").__int__()).getValue();
                for (int j = 1; j < col; j++)
                    space = space + " ";
                stderr.println(space + "^");
            }
        }

        if (value instanceof PyJavaInstance) {
            Object javaError = value.__tojava__(Throwable.class);

            if (javaError != null && javaError != Py.NoConversion) {
                stderr.println(getStackTrace((Throwable) javaError));
            }
        }
        stderr.println(formatException(type, value, tb));
    }

    static String formatException(PyObject type, PyObject value, PyObject tb) {
        StringBuffer buf = new StringBuffer();

        PyObject typeName;
        if (type instanceof PyClass) {
            buf.append(((PyClass) type).__name__);
        } else {
            buf.append(type.__str__());
        }
        if (value != Py.None) {
            buf.append(": ");
            if (__builtin__.isinstance(value, (PyClass) Py.SyntaxError)) {
                buf.append(value.__getitem__(0).__str__());
            } else {
                buf.append(value.__str__());
            }
        }
        return buf.toString();
    }

    /* Equivalent to Python's assert statement */
    public static void assert_(PyObject test, PyObject message) {
        if (!test.__nonzero__()) {
            throw new PyException(Py.AssertionError, message);
        }
    }

    public static void assert_(PyObject test) {
        assert_(test, Py.None);
    }

    /* Helpers to implement finally clauses */
    public static void addTraceback(Throwable t, PyFrame frame) {
        PyException e = Py.JavaError(t);

        //Add another traceback object to the exception if needed
        if (e.traceback.tb_frame != frame) {
            e.traceback = new PyTraceback(e.traceback);
        }
    }

    /* Helpers to implement except clauses */
    public static PyException setException(Throwable t, PyFrame frame) {
        PyException pye = Py.JavaError(t);
        pye.instantiate();

        // attach catching frame
        if (frame != null && pye.traceback.tb_frame != frame) {
            pye.traceback = new PyTraceback(pye.traceback);
        }

        ThreadState ts = getThreadState();

        ts.exception = pye;

        return pye;
    }

    public static boolean matchException(PyException pye, PyObject e) {
        pye.instantiate();
        // FIXME, see bug 737978
        //
        // A special case for IOError's to allow them to also match
        // java.io.IOExceptions.  This is a hack for 1.0.x until I can do
        // it right in 1.1
        if (e == Py.IOError) {
            if (__builtin__.isinstance(pye.value, PyJavaClass.lookup(java.io.IOException.class))) {
                return true;
            }
        }
        // FIXME too, same approach for OutOfMemoryError
        if (e == Py.MemoryError) {
            if (__builtin__.isinstance(pye.value, PyJavaClass.lookup(java.lang.OutOfMemoryError.class))) {
                return true;
            }
        }
        if (e instanceof PyClass) {
            return __builtin__.isinstance(pye.value, (PyClass) e);
        } else {
            if (e == pye.type)
                return true;
            if (e instanceof PyTuple) {
                PyObject[] l = ((PyTuple) e).getArray();
                for (int i = 0; i < l.length; i++) {
                    if (matchException(pye, l[i]))
                        return true;
                }
            }
            return false;
        }
    }

    /* Implement the raise statement */
    // reraise the current exception
    public static PyException makeException() {
        ThreadState ts = getThreadState();
        if (ts.exception == null) {
            throw Py.ValueError("no exception to reraise");
        }
        return ts.exception;
    }

    public static PyException makeException(PyObject type) {
        if (type instanceof PyInstance) {
            return new PyException(type.fastGetClass(), type);
        } else {
            return makeException(type, Py.None);
        }
    }

    public static PyException makeException(PyObject type, PyObject value) {
        if (type instanceof PyInstance) {
            if (value != Py.None) {
                throw TypeError("instance exceptions may not have " + "a separate value");
            } else {
                return new PyException(type.fastGetClass(), type);
            }
        }
        PyException exc = new PyException(type, value);
        exc.instantiate();
        return exc;
    }

    public static PyException makeException(PyObject type, PyObject value, PyObject traceback) {
        if (type instanceof PyInstance) {
            if (value != Py.None) {
                throw TypeError("instance exceptions may not have " + "a separate value");
            } else {
                type = type.fastGetClass();
                //return new PyException(type.__class__, type);
            }
        }

        if (traceback == None)
            return new PyException(type, value);
        if (!(traceback instanceof PyTraceback))
            throw TypeError("raise 3rd arg must be traceback or None");

        return new PyException(type, value, (PyTraceback) traceback);
    }

    public static PyObject runCode(PyCode code, PyObject locals, PyObject globals) {
        PyFrame f;
        if (locals == null) {
            if (globals != null) {
                locals = globals;
            } else {
                locals = Py.getFrame().getf_locals();
            }
        }

        if (globals == null)
            globals = Py.getFrame().f_globals;

        PyTableCode tc = null;
        if (code instanceof PyTableCode)
            tc = (PyTableCode) code;

        f = new PyFrame(tc, locals, globals, Py.getThreadState().systemState.builtins);
        return code.call(f);
    }

    public static void exec(PyObject o, PyObject globals, PyObject locals) {
        PyCode code;
        if (o instanceof PyCode) {
            code = (PyCode) o;
            if (locals == null && o instanceof PyTableCode && ((PyTableCode) o).hasFreevars()) {
                throw Py.TypeError("code object passed to exec may not contain free variables");
            }
        } else {
            String contents = null;
            if (o instanceof PyString)
                contents = o.toString();
            else if (o instanceof PyFile) {
                PyFile fp = (PyFile) o;
                if (fp.closed)
                    return;
                contents = fp.read().toString();
            } else
                throw Py.TypeError("exec: argument 1 must be string, code or file object");
            code = Py.compile_flags(contents, "<string>", "exec", Py.getCompilerFlags());
        }
        Py.runCode(code, locals, globals);
    }

    private static ThreadStateMapping threadStateMapping = null;

    public static final ThreadState getThreadState() {
        return getThreadState(null);
    }

    public static final ThreadState getThreadState(PySystemState newSystemState) {
        if (threadStateMapping == null) {
            synchronized (Py.class) {
                if (threadStateMapping == null)
                    threadStateMapping = ThreadStateMapping.makeMapping();
            }
        }
        return threadStateMapping.getThreadState(newSystemState);
    }

    public static final PySystemState setSystemState(PySystemState newSystemState) {
        ThreadState ts = getThreadState(newSystemState);
        PySystemState oldSystemState = ts.systemState;
        if (oldSystemState != newSystemState) {
            //System.err.println("Warning: changing systemState "+
            //                   "for same thread!");
            ts.systemState = newSystemState;
        }
        return oldSystemState;
    }

    public static final PySystemState getSystemState() {
        return getThreadState().systemState;
        //defaultSystemState;
    }

    /* Get and set the current frame */

    public static PyFrame getFrame() {
        //System.out.println("getFrame");
        ThreadState ts = getThreadState();
        if (ts == null)
            return null;
        return ts.frame;
    }

    public static void setFrame(PyFrame f) {
        //System.out.println("setFrame");
        getThreadState().frame = f;
    }

    /* These are not used anymore.  Uncomment them if there is a future
       clamor to make this functionality more easily usable
       public static void pushFrame(PyFrame f) {
       ThreadState ts = getThreadState();
       f.f_back = ts.frame;
       if (f.f_builtins == null) f.f_builtins = f.f_back.f_builtins;
       ts.frame = f;
       }

       public static PyFrame popFrame() {
       ThreadState ts = getThreadState();
       PyFrame f = ts.frame.f_back;
       ts.frame = f;
       return f;
       }
    */

    /* A collection of functions for implementing the print statement */

    public static StdoutWrapper stderr;
    static StdoutWrapper stdout;

    //public static StdinWrapper stdin;

    public static void print(PyObject file, PyObject o) {
        if (file == None)
            print(o);
        else
            new FixedFileWrapper(file).print(o);
    }

    public static void printComma(PyObject file, PyObject o) {
        if (file == None)
            printComma(o);
        else
            new FixedFileWrapper(file).printComma(o);
    }

    public static void println(PyObject file, PyObject o) {
        if (file == None)
            println(o);
        else
            new FixedFileWrapper(file).println(o);
    }

    public static void printlnv(PyObject file) {
        if (file == None)
            println();
        else
            new FixedFileWrapper(file).println();
    }

    public static void print(PyObject o) {
        stdout.print(o);
    }

    public static void printComma(PyObject o) {
        stdout.printComma(o);
    }

    public static void println(PyObject o) {
        stdout.println(o);
    }

    public static void println() {
        stdout.println();
    }

    /* A collection of convenience functions for converting PyObjects
       to Java primitives */

    public static boolean py2boolean(PyObject o) {
        return o.__nonzero__();
    }

    public static byte py2byte(PyObject o) {
        if (o instanceof PyInteger)
            return (byte) ((PyInteger) o).getValue();

        Object i = o.__tojava__(Byte.TYPE);
        if (i == null || i == Py.NoConversion)
            throw Py.TypeError("integer required");
        return ((Byte) i).byteValue();
    }

    public static short py2short(PyObject o) {
        if (o instanceof PyInteger)
            return (short) ((PyInteger) o).getValue();

        Object i = o.__tojava__(Short.TYPE);
        if (i == null || i == Py.NoConversion)
            throw Py.TypeError("integer required");
        return ((Short) i).shortValue();
    }

    public static int py2int(PyObject o) {
        return py2int(o, "integer required");
    }

    public static int py2int(PyObject o, String msg) {
        if (o instanceof PyInteger)
            return (int) ((PyInteger) o).getValue();
        Object obj = o.__tojava__(Integer.TYPE);
        if (obj == Py.NoConversion)
            throw Py.TypeError(msg);
        return ((Integer) obj).intValue();
    }

    public static long py2long(PyObject o) {
        if (o instanceof PyInteger)
            return (long) ((PyInteger) o).getValue();

        Object i = o.__tojava__(Long.TYPE);
        if (i == null || i == Py.NoConversion)
            throw Py.TypeError("integer required");
        return ((Long) i).longValue();
    }

    public static float py2float(PyObject o) {
        if (o instanceof PyFloat)
            return (float) ((PyFloat) o).getValue();
        if (o instanceof PyInteger)
            return (float) ((PyInteger) o).getValue();

        Object i = o.__tojava__(Float.TYPE);
        if (i == null || i == Py.NoConversion)
            throw Py.TypeError("float required");
        return ((Float) i).floatValue();
    }

    public static double py2double(PyObject o) {
        if (o instanceof PyFloat)
            return (double) ((PyFloat) o).getValue();
        if (o instanceof PyInteger)
            return (double) ((PyInteger) o).getValue();

        Object i = o.__tojava__(Double.TYPE);
        if (i == null || i == Py.NoConversion)
            throw Py.TypeError("float required");
        return ((Double) i).doubleValue();
    }

    public static char py2char(PyObject o) {
        return py2char(o, "char required");
    }

    public static char py2char(PyObject o, String msg) {
        if (o instanceof PyString) {
            PyString s = (PyString) o;
            if (s.__len__() != 1)
                throw Py.TypeError(msg);
            return s.toString().charAt(0);
        }
        if (o instanceof PyInteger) {
            return (char) ((PyInteger) o).getValue();
        }

        Object i = o.__tojava__(Character.TYPE);
        if (i == null || i == Py.NoConversion)
            throw Py.TypeError(msg);
        return ((Character) i).charValue();
    }

    public static void py2void(PyObject o) {
        if (o != Py.None) {
            throw Py.TypeError("None required for void return");
        }
    }

    private static PyString[] letters = null;

    public static final PyString makeCharacter(Character o) {
        return makeCharacter(o.charValue());
    }

    static final PyString makeCharacter(char c) {
        return makeCharacter(c, false);
    }

    static final PyString makeCharacter(char c, boolean explicitUnicode) {
        if (explicitUnicode || c > 255) {
            return new PyUnicode(new Character(c).toString());
        }

        if (letters == null) {
            letters = new PyString[256];
            for (char j = 0; j < 256; j++) {
                letters[j] = new PyString(new Character(j).toString());
            }
        }
        return letters[c];
    }

    /**
     * Uses the PyObjectAdapter passed to {@link PySystemState#initialize} to turn o into a PyObject.
     *
     * @see ClassicPyObjectAdapter - default PyObjectAdapter type
     */
    public static PyObject java2py(Object o) {
        return getAdapter().adapt(o);
    }

    /**
     * @return the ExtensiblePyObjectAdapter used by java2py.
     */
    public static ExtensiblePyObjectAdapter getAdapter() {
        if (adapter == null) {
            adapter = new ClassicPyObjectAdapter();
        }
        return adapter;
    }

    /**
     * Set the ExtensiblePyObjectAdapter used by java2py.
     *
     * @param adapter The new ExtensiblePyObjectAdapter
     */
    protected static void setAdapter(ExtensiblePyObjectAdapter adapter) {
        Py.adapter = adapter;
    }

    /**
     * Handles wrapping Java objects in PyObject to expose them to jython.
     */
    private static ExtensiblePyObjectAdapter adapter;

    public static PyObject makeClass(String name, PyObject[] bases, PyCode code, PyObject doc) {
        return makeClass(name, bases, code, doc, null, null);
    }

    public static PyObject makeClass(String name, PyObject[] bases, PyCode code, PyObject doc, PyObject[] closure_cells) {
        return makeClass(name, bases, code, doc, null, closure_cells);
    }

    public static PyObject makeClass(String name, PyObject[] bases, PyCode code, PyObject doc, Class proxyClass) {
        return makeClass(name, bases, code, doc, proxyClass, null);
    }

    private static Class[] pyClassCtrSignature = { String.class, PyTuple.class, PyObject.class, Class.class };

    static private final PyType CLASS_TYPE = PyType.fromClass(PyClass.class);

    public static PyObject makeClass(String name, PyObject[] bases, PyCode code, PyObject doc, Class proxyClass,
            PyObject[] closure_cells) {
        PyFrame frame = getFrame();
        PyObject globals = frame.f_globals;

        PyObject dict = code.call(Py.EmptyObjects, Py.NoKeywords, globals, Py.EmptyObjects, new PyTuple(closure_cells));
        if (doc != null)
            dict.__setitem__("__doc__", doc);

        PyObject metaclass;

        metaclass = dict.__finditem__("__metaclass__");

        if (metaclass == null) {
            if (bases.length != 0) {
                PyObject base = bases[0];

                if (base instanceof PyMetaClass) {
                    // jython-only, experimental PyMetaClass hook
                    // xxx keep?
                    try {
                        java.lang.reflect.Constructor ctor = base.getClass().getConstructor(pyClassCtrSignature);
                        return (PyObject) ctor.newInstance(new Object[] { name, new PyTuple(bases), dict, proxyClass });
                    } catch (Exception e) {
                        throw Py.TypeError("meta-class fails to supply proper " + "ctr: " + base.safeRepr());
                    }
                }
                metaclass = base.__findattr__("__class__");
                if (metaclass == null) {
                    metaclass = base.getType();
                }
            } else {
                if (globals != null)
                    metaclass = globals.__finditem__("__metaclass__");
            }
        }

        if (metaclass == null || metaclass == CLASS_TYPE
                || (metaclass instanceof PyJavaClass && ((PyJavaClass) metaclass).proxyClass == Class.class)) {
            boolean more_general = false;
            for (int i = 0; i < bases.length; i++) {
                if (!(bases[i] instanceof PyClass)) {
                    metaclass = bases[i].getType();
                    more_general = true;
                    break;
                }
            }
            if (!more_general)
                return new PyClass(name, new PyTuple(bases), dict, proxyClass);
        }

        if (proxyClass != null) {
            throw Py.TypeError("the meta-class cannot handle java subclassing");
        }

        return metaclass.__call__(new PyString(name), new PyTuple(bases), dict);
    }

    private static int nameindex = 0;

    public static synchronized String getName() {
        String name = "org.python.pycode._pyx" + nameindex;
        nameindex += 1;
        return name;
    }

    public static CompilerFlags getCompilerFlags() {
        return getCompilerFlags(0, false);
    }

    public static CompilerFlags getCompilerFlags(int flags, boolean dont_inherit) {
        CompilerFlags cflags = null;
        if (dont_inherit) {
            cflags = new CompilerFlags(flags);
        } else {
            PyFrame frame = Py.getFrame();
            if (frame != null && frame.f_code != null) {
                cflags = new CompilerFlags(frame.f_code.co_flags | flags);
            }
        }
        return cflags;
    }

    // w/o compiler-flags

    public static PyCode compile(modType node, String filename) {
        return compile(node, getName(), filename);
    }

    public static PyCode compile(modType node, String name, String filename) {
        return compile(node, name, filename, true, false);
    }

    public static PyCode compile(modType node, String name, String filename, boolean linenumbers, boolean printResults) {
        return compile_flags(node, name, filename, linenumbers, printResults, null);
    }

    public static PyCode compile(byte[] istream, String filename, String type) {
        return compile_flags(istream, filename, type, null);
    }

    // with compiler-flags

    public static PyCode compile_flags(modType node, String name, String filename, boolean linenumbers,
            boolean printResults, CompilerFlags cflags) {
        try {
            ByteArrayOutputStream ostream = new ByteArrayOutputStream();
            Module.compile(node, ostream, name, filename, linenumbers, printResults, false, cflags);

            saveClassFile(name, ostream);

            return BytecodeLoader.makeCode(name, ostream.toByteArray(), filename);
        } catch (Throwable t) {
            throw parser.fixParseError(null, t, filename);
        }
    }

    public static PyCode compile_flags(byte[] istream, String filename, String type, CompilerFlags cflags) {
        modType node = parser.parse(istream, type, filename, cflags);
        boolean printResults = false;
        if (type.equals("single"))
            printResults = true;
        return Py.compile_flags(node, getName(), filename, true, printResults, cflags);
    }

    public static PyCode compile_flags(String data, String filename, String type, CompilerFlags cflags) {
        return Py.compile_flags(PyString.to_bytes(data + "\n\n"), filename, type, cflags);
    }

    public static PyObject compile_command_flags(String string, String filename, String kind, CompilerFlags cflags,
            boolean stdprompt) {
        modType node = parser.partialParse(string + "\n", kind, filename, cflags, stdprompt);

        if (node == null)
            return Py.None;
        return Py.compile_flags(node, Py.getName(), filename, true, true, cflags);
    }

    public static PyObject[] unpackSequence(PyObject o, int length) {
        if (o instanceof PyTuple) {
            PyTuple tup = (PyTuple) o;
            //System.err.println("unpack tuple");
            if (tup.__len__() == length)
                return tup.getArray();
            throw Py.ValueError("unpack tuple of wrong size");
        }

        PyObject[] ret = new PyObject[length];
        PyObject iter = o.__iter__();
        try {
            for (int i = 0; i < length; i++) {
                PyObject tmp = iter.__iternext__();
                if (tmp == null) {
                    throw Py.ValueError("unpack sequence too short");
                }
                ret[i] = tmp;
            }
        } catch (PyException exc) {
            if (Py.matchException(exc, Py.AttributeError)) {
                throw Py.TypeError("unpack non-sequence");
            } else {
                throw exc;
            }
        }

        if (iter.__iternext__() != null) {
            throw Py.ValueError("unpack sequence too long");
        }
        return ret;
    }

    public static PyObject iter(PyObject seq, String message) {
        try {
            return seq.__iter__();
        } catch (PyException exc) {
            if (Py.matchException(exc, Py.TypeError))
                throw Py.TypeError(message);
            throw exc;
        }
    }

    private static IdImpl idimpl = IdImpl.getInstance();

    public static long id(PyObject o) {
        return idimpl.id(o);
    }

    public static String idstr(PyObject o) {
        return idimpl.idstr(o);
    }

    public static long java_obj_id(Object o) {
        return idimpl.java_obj_id(o);
    }

    public static String safeRepr(PyObject o) {
        return o.safeRepr();
    }

    public static void printResult(PyObject ret) {
        Py.getThreadState().systemState.invoke("displayhook", ret);
    }

    public static final int ERROR = -1;
    public static final int WARNING = 0;
    public static final int MESSAGE = 1;
    public static final int COMMENT = 2;
    public static final int DEBUG = 3;

    public static void maybeWrite(String type, String msg, int level) {
        if (level <= Options.verbose) {
            System.err.println(type + ": " + msg);
        }
    }

    public static void writeError(String type, String msg) {
        maybeWrite(type, msg, ERROR);
    }

    public static void writeWarning(String type, String msg) {
        maybeWrite(type, msg, WARNING);
    }

    public static void writeMessage(String type, String msg) {
        maybeWrite(type, msg, MESSAGE);
    }

    public static void writeComment(String type, String msg) {
        maybeWrite(type, msg, COMMENT);
    }

    public static void writeDebug(String type, String msg) {
        maybeWrite(type, msg, DEBUG);
    }

    public static void saveClassFile(String name, ByteArrayOutputStream bytestream) {
        String dirname = Options.proxyDebugDirectory;
        if (dirname == null)
            return;

        byte[] bytes = bytestream.toByteArray();
        File dir = new File(dirname);
        File file = makeFilename(name, dir);
        new File(file.getParent()).mkdirs();
        try {
            FileOutputStream o = new FileOutputStream(file);
            o.write(bytes);
            o.close();
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    private static File makeFilename(String name, File dir) {
        int index = name.indexOf(".");
        if (index == -1)
            return new File(dir, name + ".class");

        return makeFilename(name.substring(index + 1, name.length()), new File(dir, name.substring(0, index)));
    }

    private static boolean abstract_issubclass(PyObject derived, PyObject cls) {
        if (derived == cls)
            return true;
        PyObject bases = derived.__findattr__("__bases__");
        if (bases == null)
            return false;
        for (int i = 0; i < bases.__len__(); i++) {
            if (abstract_issubclass(bases.__getitem__(i), cls))
                return true;
        }
        return false;
    }

    public static boolean isInstance(PyObject obj, PyObject cls) {
        if (cls instanceof PyType) {
            PyType objtype = obj.getType();
            if (objtype == cls)
                return true;
            return objtype.isSubType((PyType) cls);
        } else if (cls instanceof PyClass) {
            if (!(obj instanceof PyInstance))
                return false;
            return ((PyClass) obj.fastGetClass()).isSubClass((PyClass) cls);
        } else if (cls.getClass() == PyTuple.class) {
            for (int i = 0; i < cls.__len__(); i++) {
                if (isInstance(obj, cls.__getitem__(i)))
                    return true;
            }
            return false;
        } else {
            if (cls.__findattr__("__bases__") == null)
                throw Py.TypeError("isinstance() arg 2 must be a class, type," + " or tuple of classes and types");
            PyObject ocls = obj.__findattr__("__class__");
            if (ocls == null)
                return false;
            return abstract_issubclass(ocls, cls);
        }
    }

    public static boolean isSubClass(PyObject derived, PyObject cls) {
        if (derived instanceof PyType && cls instanceof PyType) {
            if (derived == cls)
                return true;
            return ((PyType) derived).isSubType((PyType) cls);
        } else if (cls instanceof PyClass && derived instanceof PyClass) {
            return ((PyClass) derived).isSubClass((PyClass) cls);
        } else if (cls.getClass() == PyTuple.class) {
            for (int i = 0; i < cls.__len__(); i++) {
                if (isSubClass(derived, cls.__getitem__(i)))
                    return true;
            }
            return false;
        } else {
            if (derived.__findattr__("__bases__") == null)
                throw Py.TypeError("issubclass() arg 1 must be a class");
            if (cls.__findattr__("__bases__") == null)
                throw Py.TypeError("issubclass() arg 2 must be a class, type," + " or tuple of classes and types");
            return abstract_issubclass(derived, cls);
        }
    }

    static PyObject[] make_array(PyObject o) {
        if (o instanceof PyTuple)
            return ((PyTuple) o).getArray();

        PyObject iter = o.__iter__();

        // Guess result size and allocate space.
        int n = 10;
        try {
            n = o.__len__();
        } catch (PyException exc) {
        }

        PyObject[] objs = new PyObject[n];

        int i;
        for (i = 0;; i++) {
            PyObject item = iter.__iternext__();
            if (item == null)
                break;
            if (i >= n) {
                if (n < 500) {
                    n += 10;
                } else {
                    n += 100;
                }
                PyObject[] newobjs = new PyObject[n];
                System.arraycopy(objs, 0, newobjs, 0, objs.length);
                objs = newobjs;
            }
            objs[i] = item;
        }

        // Cut back if guess was too large.
        if (i < n) {
            PyObject[] newobjs = new PyObject[i];
            System.arraycopy(objs, 0, newobjs, 0, i);
            objs = newobjs;
        }
        return objs;
    }

}

/** @deprecated **/
class FixedFileWrapper extends StdoutWrapper {
    private PyObject file;

    public FixedFileWrapper(PyObject file) {
        name = "fixed file";
        this.file = file;

        if (file instanceof PyJavaInstance) {
            Object tmp = file.__tojava__(OutputStream.class);
            if ((tmp != Py.NoConversion) && (tmp != null)) {
                OutputStream os = (OutputStream) tmp;
                this.file = new PyFile(os, "<java OutputStream>");
            } else {
                tmp = file.__tojava__(Writer.class);
                if ((tmp != Py.NoConversion) && (tmp != null)) {
                    Writer w = (Writer) tmp;
                    this.file = new PyFile(w, "<java Writer>");
                }
            }
        }
    }

    protected PyObject myFile() {
        return file;
    }
}

/**
* A code object wrapper for a python function.
*/
final class JavaCode extends PyCode {
    private PyObject func;

    public JavaCode(PyObject func) {
        this.func = func;
        if (func instanceof PyReflectedFunction)
            this.co_name = ((PyReflectedFunction) func).__name__;
    }

    public PyObject call(PyFrame frame, PyObject closure) {
        System.out.println("call #1");
        return Py.None;
    }

    public PyObject call(PyObject args[], String keywords[], PyObject globals, PyObject[] defaults, PyObject closure) {
        return func.__call__(args, keywords);
    }

    public PyObject call(PyObject self, PyObject args[], String keywords[], PyObject globals, PyObject[] defaults,
            PyObject closure) {
        return func.__call__(self, args, keywords);
    }

    public PyObject call(PyObject globals, PyObject[] defaults, PyObject closure) {
        return func.__call__();
    }

    public PyObject call(PyObject arg1, PyObject globals, PyObject[] defaults, PyObject closure) {
        return func.__call__(arg1);
    }

    public PyObject call(PyObject arg1, PyObject arg2, PyObject globals, PyObject[] defaults, PyObject closure) {
        return func.__call__(arg1, arg2);
    }

    public PyObject call(PyObject arg1, PyObject arg2, PyObject arg3, PyObject globals, PyObject[] defaults,
            PyObject closure) {
        return func.__call__(arg1, arg2, arg3);
    }
}

/**
* A function object wrapper for a java method which comply with the
* PyArgsKeywordsCall standard.
*/
final class JavaFunc extends PyObject {
    java.lang.reflect.Method method;

    public JavaFunc(java.lang.reflect.Method method) {
        this.method = method;
    }

    public PyObject __call__(PyObject[] args, String[] kws) {
        Object[] margs = new Object[] { args, kws };
        try {
            return Py.java2py(method.invoke(null, margs));
        } catch (Throwable t) {
            throw Py.JavaError(t);
        }
    }

    public PyObject _doget(PyObject container) {
        return _doget(container, null);
    }

    public PyObject _doget(PyObject container, PyObject wherefound) {
        if (container == null)
            return this;
        return new PyMethod(container, this, wherefound);
    }

    public boolean _doset(PyObject container) {
        throw Py.TypeError("java function not settable: " + method.getName());
    }
}
TOP

Related Classes of org.python.core.Py

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.